package management

import (
	"context"
	"encoding/json"
	"net/http"
	"strconv"
	"time"

	"github.com/gorilla/mux"
	"github.com/jsrccb/nachuan/common"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func initCostMgrApi(r *mux.Router) {
	s := r.PathPrefix("/cost").Subrouter()
	// s.HandleFunc("/list", UserListHandler)
	s.HandleFunc("/updsave", handleCostSave)
	//请求/order/handleOrderqueryall?ordertype=xxx&skip=1&limit=1
	s.HandleFunc("/query", handleCostQuery)

	s.HandleFunc("/delbyid", handleDelCostById)
	// ents := r.PathPrefix("/agentcustomevent").Subrouter()
	// ents.HandleFunc("/queryall", handleOrderEventqueryall)
}

type CostMgr struct {
	client *mongo.Client
	Cost   *mongo.Collection
}

var (
	G_CostMgr *CostMgr
)

func handleDelCostById(resp http.ResponseWriter, req *http.Request) {
	var (
		err    error
		bytes  []byte
		costId string
		// rolelimit     *common.RoleLimits
	)

	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	costId = req.PostForm.Get("costid")

	if err = G_CostMgr.delCostById(costId); err == nil {
		if bytes, err = common.BuildResponse(0, "success", "收款状态删除成功"); err == nil {
			resp.Write(bytes)
		}
	} else {
		goto ERR
	}
	// fmt.Println(cluein
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func (costMgr *CostMgr) delCostById(costid string) (err error) {

	var (
		// resultOne *mongo.InsertOneResult
		// update *common.HostInfo
		ctx context.Context
		// basecoll  *common.Collection
	)

	_, err = costMgr.Cost.DeleteOne(ctx, bson.M{"costId": costid})

	return
}

func handleCostSave(resp http.ResponseWriter, req *http.Request) {
	var (
		err         error
		bytes       []byte
		cost        *common.Cost
		costinfostr string
		// rolelimit     *common.RoleLimits
	)

	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	costinfostr = req.PostForm.Get("costinfo")

	if err = json.Unmarshal([]byte(costinfostr), &cost); err != nil {
		goto ERR
	}

	if err = G_CostMgr.saveCost(cost); err == nil {
		if bytes, err = common.BuildResponse(0, "success", cost); err == nil {
			resp.Write(bytes)
		}
	} else {
		goto ERR
	}
	// fmt.Println(cluein

	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleCostUpd(resp http.ResponseWriter, req *http.Request) {
	var (
		err         error
		bytes       []byte
		cost        *common.Cost
		costinfostr string
		// rolelimit     *common.RoleLimits
	)

	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	costinfostr = req.PostForm.Get("costinfostr")

	if err = json.Unmarshal([]byte(costinfostr), &cost); err != nil {
		goto ERR
	}

	if err = G_CostMgr.saveCost(cost); err == nil {
		if bytes, err = common.BuildResponse(0, "success", cost); err == nil {
			resp.Write(bytes)
		}
	} else {
		goto ERR
	}
	// fmt.Println(cluein

	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleCostQuery(resp http.ResponseWriter, req *http.Request) {
	var (
		err   error
		bytes []byte
		// entclueinfo *common.EntClue
		querySet   []bson.M
		skipParam  string
		limitParam string
		skip       int
		limit      int
		costinfos  []*common.Cost
		countcost  int64
		// rolelimit     *common.RoleLimits

		queryBson bson.M

		costfromtype string //成本来源类型  订单、客户（用来区分是订单收款还是客户收款）
		costno       string //成本编号  订单编号或者代账客户管理里面的客户编号
		costfrom     string //成本来源 根据订单类别分别显示为：代账客户、注册代账订单、迁入订单、变更订单、注销订单、商标订单、建筑资质订单、其他订单
		coststatus   string //成本状态 出纳录入成功显示“出纳已确认”、内账会计角色确认ok则显示“内账会计已确认”
		custommgr    string //客户经理
		accountant   string //主管会计
	)

	query := req.URL.Query()
	costfromtype = query.Get("costfromtype")
	costno = query.Get("costno")
	costfrom = query.Get("costfrom")
	coststatus = query.Get("coststatus")
	accountant = query.Get("accountant")
	custommgr = query.Get("custommgr")

	skipParam = query.Get("skip")
	limitParam = query.Get("limit")

	if skip, err = strconv.Atoi(skipParam); err != nil {
		skip = 0
	}

	if limit, err = strconv.Atoi(limitParam); err != nil {
		limit = 100
	}

	if costfromtype != "" {
		qcostfromtype := bson.M{"costFromType": costfromtype}
		querySet = append(querySet, qcostfromtype)
	}
	if costno != "" {
		qcostno := bson.M{"costNo": costno}
		querySet = append(querySet, qcostno)
	}
	if costfrom != "" {
		qcostfrom := bson.M{"costFrom": costfrom}
		querySet = append(querySet, qcostfrom)
	}

	if coststatus != "" {
		qcoststatus := bson.M{"costStatus": coststatus}
		querySet = append(querySet, qcoststatus)
	}
	if accountant != "" {
		qaccountant := bson.M{"accountant": accountant}
		querySet = append(querySet, qaccountant)
	}
	if custommgr != "" {
		qcustommgr := bson.M{"customMgr": custommgr}
		querySet = append(querySet, qcustommgr)
	}

	queryBson = bson.M{"$and": querySet}

	costmap := make(map[string]interface{})
	countcost, _ = G_CostMgr.countCostbySet(queryBson)
	// fmt.Println(countclue)

	if costinfos, err = G_CostMgr.queryCostbySet(queryBson, int64(skip), int64(limit)); err != nil {
		goto ERR
	}
	costmap["costcount"] = countcost
	costmap["costinfos"] = costinfos
	if bytes, err = common.BuildResponse(0, "success", costmap); err == nil {
		resp.Write(bytes)
	} else {
		goto ERR
	}

	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func (costMgr *CostMgr) saveCost(cost *common.Cost) (err error) {

	var (
		// resultOne *mongo.InsertOneResult
		// update *common.HostInfo
		ctx context.Context
		// basecoll  *common.Collection
		countCost int64
	)

	if cost.CostId == "" {
		countCost, err = costMgr.Cost.CountDocuments(ctx, bson.M{"costNo": cost.CostNo})
		cost.CostId = cost.CostNo + strconv.FormatInt(countCost+1, 10)
		_, err = costMgr.Cost.InsertOne(context.TODO(), cost)

	} else {
		// collMgr.CollColl.FindOne(ctx, bson.M{"collId": coll.CollId}).Decode(&basecoll)
		//保留开始的代账日期
		// if basecoll.AgentBeginDate != "" {
		// 	coll.AgentBeginDate = basecoll.AgentBeginDate
		// }
		_, err = costMgr.Cost.UpdateOne(ctx, bson.M{"costId": cost.CostId}, bson.M{"$set": cost})

	}

	return
}

func (costMgr *CostMgr) countCostbySet(setElements bson.M) (countCost int64, err error) {
	var (
		// resultOne *mongo.InsertOneResult
		ctx context.Context
		// update *common.HostInfo
	)
	ctx, _ = context.WithTimeout(context.Background(), 15*time.Second)
	if len(setElements["$and"].([]primitive.M)) == 0 {
		// fmt.Println(0)
		// countCost = 0
		countCost, err = costMgr.Cost.CountDocuments(ctx, bson.M{})
	} else {
		// fmt.Println(1)
		countCost, err = costMgr.Cost.CountDocuments(ctx, setElements)
	}
	return
}

func InitCostMgr() (err error) {

	G_CostMgr = &CostMgr{
		client: G_MongoMgr.client,
		Cost:   G_MongoMgr.MongdbConnect.Collection("cost"),
	}

	return
}

func (costMgr *CostMgr) queryCostbySet(setElements bson.M, skip int64, limit int64) (costs []*common.Cost, err error) {

	var (
		// resultOne *mongo.InsertOneResult
		cursor     *mongo.Cursor
		cost       *common.Cost
		findopt    *options.FindOptions
		ctx        context.Context
		customSort *common.SortById
		// update *common.HostInfo
	)

	ctx, _ = context.WithTimeout(context.Background(), 10*time.Second)

	findopt = &options.FindOptions{}
	customSort = &common.SortById{
		SortOrder: -1,
	}
	findopt.SetSort(customSort)

	if limit > 0 && skip >= 0 {
		findopt.SetLimit(limit)
		findopt.SetSkip(limit * skip)

	} else {
		return
	}
	if len(setElements["$and"].([]primitive.M)) == 0 {
		// fmt.Println(0)
		cursor, err = costMgr.Cost.Find(context.TODO(), bson.M{}, findopt)
	} else {
		// fmt.Println(1)
		cursor, err = costMgr.Cost.Find(context.TODO(), setElements, findopt)
	}
	defer cursor.Close(ctx)

	for cursor.Next(ctx) {
		cost = &common.Cost{}
		if err = cursor.Decode(cost); err != nil {
			continue
		}
		costs = append(costs, cost)
	}
	// fmt.Println("doccount:" + strconv.FormatInt(doccount, 10))
	return
}
